const chokidar = require('chokidar');
const fs = require('fs');
const chalk = require('chalk');

// promise化
function promisify(fn) {
  return function() {
    var args = arguments;
    return new Promise(function(resolve, reject) {
      [].push.call(args, function(err, result) {
        if(err) {
          console.log(chalk.red(err));
          reject(err);
        }else {
          resolve(result);
        }
      });
      fn.apply(null, args);
    });
  }
}

const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);

class VueRouteWebpackPlugin {
  constructor(options = {}) {
    this.filePath = options.filePath.replace(/\\/g, '/');   // 监听.vue文件的路径
    this.routePath = options.routePath // 生成 router.js 文件的路径
    this.isVue3 = options.isVue3 || false // 是否使用vue3.0的模板
    this.isHistory = options.isHistory || false
    this.fileList = [];
  }

  apply(compiler) {
    compiler.hooks.afterPlugins.tap('VueRouteWebpackPlugin', () => {
      this.doSetRoute()
      if (process.env.NODE_ENV === 'development') {
        const watcher = chokidar.watch(this.filePath, {
          ignored: /(^|[\/\\])\../,
          persistent: true
        });

        watcher.on('change', () => {
          this.doSetRoute()
        })
      }
    })
  }

  doSetRoute() {
    this.fileList = [];
    this.readDirRecur(this.filePath, (path) => {
      this.fileList.push(path);
    }).then(() => {
      this.writeFile();
    }).catch(function(err) {
      console.log(chalk.red(err));
    })
  }

  writeFile(){
    const vueFiles = this.fileList
      .filter(item => item.endsWith('.vue'))
      .map(item => {
        const _filePath = item.substring(item.indexOf(this.filePath) + this.filePath.length);
        return `{
          path: '${_filePath.endsWith('/index.vue') ? _filePath.slice(0, -9)  : _filePath.slice(0, -4)}',
          component: () => import('${item}')
        }`
      })
    const text = this.isVue3 ? `
      import { createRouter, ${this.isHistory ? 'createWebHistory' : 'createWebHashHistory' } } from 'vue-router';
      import Router from 'vue-router';
      export default createRouter({
      history: ${this.isHistory ? 'createWebHistory(),' : 'createWebHashHistory(),' }
      routes: [
      ${vueFiles}
      ]
      })` : `
      import Vue from 'vue';
      import Router from 'vue-router';
      Vue.use(Router)
      export default new Router({
      ${this.isHistory ? "mode: 'history'," : '' }
      routes: [
      ${vueFiles}
      ]
      })`

    fs.writeFile(this.routePath, text, function (error) {
      if (error) {
        console.log(chalk.red('写入失败'));
      } else {
        console.log(chalk.green('写入成功了'));
      }
    })
  }

  readDirRecur(file, callback) {
    return readdir(file).then((files) => {
      files = files.map((item) => {
        var fullPath = file + '/' + item;
 
        return stat(fullPath).then((stats) => {
            if (stats.isDirectory()) {
                return this.readDirRecur(fullPath, callback);
            } else {
              /*not use ignore files*/
              if(item[0] == '.'){
                //console.log(item + ' is a hide file.');
              } else {
                callback && callback(fullPath)
              }
            }
          })
      });
      return Promise.all(files);
    });
  }
}

module.exports = VueRouteWebpackPlugin;
